﻿using Memo.Electricity.Engine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using UnityEngine;

namespace Memo.Electricity.Game
{
	public class CMovePlatform : MemoBehaviour
	{
		public enum EMovePlatformType
		{
			BACK_FORTH,
			LOOP,
			ONCE
		}
		[SerializeField]
		private EMovePlatformType mPlatformType;

		public int NodeCount
		{
			get
			{
				if (mLocalPositions == null || mLocalPositions.Length <= 1)
				{
					mLocalPositions = new Vector3[1];
					mLocalPositions[0] = Vector3.zero;
				}
				return mLocalPositions.Length;
			}
		}

		public Vector3[] WorldPositions { get; private set; }
		public EMovePlatformType PlatformType { get => mPlatformType; }

		[SerializeField]
		private float mSpeed;
		[SerializeField, HideInInspector]
		public Vector3[] mLocalPositions = new Vector3[1];
		[SerializeField, HideInInspector]
		public float[] mWaitTimes = new float[1];

		private Action mOnTriggerEnter;

		private void Awake()
		{
			//计算每个节点的世界坐标
			WorldPositions = new Vector3[NodeCount];
			for(int i = 0; i < NodeCount; i++)
			{
				WorldPositions[i] = transform.TransformPoint(mLocalPositions[i]);
			}
		}

		private void OnEnable()
		{
			StartCoroutine(MoveUpdate());
		}

		private IEnumerator MoveUpdate()
		{
			if (mLocalPositions.Length == 1)
				yield break;
			int currentIndex = 0;
			int targetIndex = 1;
			int dir = 1;

			//临时做法，用闭包捕获变量
			mOnTriggerEnter = () =>
			{
				if (WorldPositions[targetIndex].y < WorldPositions[currentIndex].y)
				{
					dir *= -1;
					int t = currentIndex;
					currentIndex = targetIndex;
					targetIndex = t;
				}
			};

			while(true)
			{
				Vector3 curPos = transform.position;
				Vector3 direction = WorldPositions[targetIndex] - curPos;
				Vector3 offset = direction.normalized * mSpeed * Time.deltaTime;
				if (offset.magnitude >= direction.magnitude)
				{
					//到达新节点
					transform.position = WorldPositions[targetIndex];
					currentIndex = targetIndex;
					targetIndex = GetNext(targetIndex, ref dir);
					yield return new WaitForSeconds(mWaitTimes[currentIndex]);
				}
				else
				{
					//在路上
					transform.position = curPos + offset;
					yield return null;
				}
			}
		}

		private int GetNext(int current, ref int dir)
		{
			if (dir != 1 && dir != -1)
				throw new ArgumentException($"The argument dir must be 1 or -1, while now it is {dir}");

			int next = current;
			next += dir;

			if(dir == 1)
			{
				if (next == NodeCount)
				{
					switch (mPlatformType)
					{
						case EMovePlatformType.BACK_FORTH:
							dir = -dir;
							next = NodeCount - 2;
							break;
						case EMovePlatformType.LOOP:
							next = 0;
							break;
						case EMovePlatformType.ONCE:
							next = -1;
							break;
					}
				}
			}
			else
			{
				if (next == -1)
				{
					switch (mPlatformType)
					{
						case EMovePlatformType.BACK_FORTH:
							dir = -dir;
							next = 1;
							break;
						case EMovePlatformType.LOOP:
							next = NodeCount - 1;
							break;
						case EMovePlatformType.ONCE:
							next = -1;
							break;
					}
				}
			}

			return next;
		}

		private void OnTriggerEnter2D(Collider2D collision)
		{
			if (!collision.isTrigger || collision.CompareTag("Player"))
			{
				mOnTriggerEnter?.Invoke();
			}
		}

	}

}

